import 'package:flutter/material.dart';
import 'package:flutter_lui/flutter_lui.dart';
import 'package:flutter_lui/src/l_style.dart';

class LPicker {
  static showPicker({
    required List<LPickerItem> items,
    String? title,
    double? itemHeight,
    String? value,
    double? maskOpacity,
  }) async {
    LDialogController? controller;
    var res = await LDialog.showBaseDialog(
        position: Alignment.bottomCenter,
        maskOpacity: maskOpacity,
        child: _LPickerView(
          itemHeight: itemHeight,
          value: value,
          items: items,
          title: title ?? '请选择',
          onChange: (v) {
            if (controller != null) {
              controller!.close(v);
            }
          },
          onCancel: () {
            if (controller != null) {
              controller!.close(0);
            }
          },
        ),
        onCreated: (v) {
          controller = v;
        });
    return res;
  }

  static showMultiPicker(
      {required List<LMultiPickerItem> items,
      String? title,
      double? itemHeight,
      List<String>? values,
      double? maskOpacity}) async {
    LDialogController? controller;
    var res = await LDialog.showBaseDialog(
        position: Alignment.bottomCenter,
        maskOpacity: maskOpacity,
        child: _LMultiPickerView(
            itemHeight: itemHeight,
            values: values,
            items: items,
            title: title ?? '请选择',
            onChange: (v) {
              if (controller != null) {
                controller!.close(v);
              }
            },
            onCancel: () {
              if (controller != null) {
                controller!.close(0);
              }
            }),
        onCreated: (v) {
          controller = v;
        });
    return res;
  }
}

class LPickerItem extends LScrollWheelItem {
  LPickerItem(
      {required String label, required String value, dynamic otherValue})
      : super(label: label, value: value, otherValue: otherValue);

  @override
  copy() {
    return LPickerItem(
      label: label,
      value: value,
      otherValue: otherValue,
    );
  }
}

class _LPickerView extends StatefulWidget {
  final String title;
  final List<LPickerItem> items;
  final String? value;
  final double? itemHeight;
  final Function(LPickerItem) onChange;
  final Function() onCancel;
  const _LPickerView(
      {required this.items,
      required this.title,
      required this.onCancel,
      required this.onChange,
      this.itemHeight,
      this.value,
      Key? key})
      : super(key: key);

  @override
  State<StatefulWidget> createState() => __LPickerView();
}

class __LPickerView extends State<_LPickerView> {
  late LPickerItem value;
  @override
  void initState() {
    super.initState();
    LPickerItem? useValue;
    if (widget.value?.isNotEmpty == true) {
      useValue = firstWhereOrNull(widget.items, (i) => i.value == widget.value);
    }
    useValue ??= widget.items[0];
    value = useValue;
  }

  handleChange(LScrollWheelItem v) {
    setState(() {
      value =
          LPickerItem(label: v.label, value: v.value, otherValue: v.otherValue);
      value.index = v.index;
    });
  }

  @override
  Widget build(BuildContext context) {
    var defaultWidth = lrpx(48);
    return LBox(
      backgroundColor: Colors.white,
      borderRadius: [lrpx(10), lrpx(10), 0, 0],
      mainAxisSize: MainAxisSize.min,
      children: [
        LBox(
          height: defaultWidth,
          borderBottom: BorderSide(color: LUI.instance.borderColor),
          direction: BoxDirections.horizontal,
          children: [
            LBox(
                child: '取消',
                width: defaultWidth,
                height: defaultWidth,
                alignment: Alignment.center,
                onTap: widget.onCancel),
            LBox(
              flex: 1,
              child: widget.title,
              fontSize: LStyle.fontSize + lrpx(2),
              fontWeight: FontWeight.bold,
              alignment: Alignment.center,
            ),
            LBox(
              child: '确定',
              width: defaultWidth,
              height: defaultWidth,
              alignment: Alignment.center,
              color: LUI.instance.primaryColor,
              onTap: () => widget.onChange(value),
            ),
          ],
        ),
        LScrollWheel(
            items: widget.items,
            value: value.value,
            itemHeight: widget.itemHeight,
            onChange: handleChange)
      ],
    );
  }
}

/// -------------------------------------------------------------------

class LMultiPickerItem extends LScrollWheelItem {
  List<LMultiPickerItem>? children;
  LMultiPickerItem(
      {required String label,
      required String value,
      dynamic otheralue,
      this.children})
      : super(label: label, value: value, otherValue: otheralue);

  @override
  copy() {
    return LMultiPickerItem(
        label: label, value: value, otheralue: otherValue, children: children);
  }
}

class _LMultiPickerView extends StatefulWidget {
  final String title;
  final List<LMultiPickerItem> items;
  final List<String>? values;
  final double? itemHeight;
  final Function(List<LMultiPickerItem>) onChange;
  final Function() onCancel;
  const _LMultiPickerView(
      {required this.title,
      required this.items,
      this.values,
      this.itemHeight,
      required this.onCancel,
      required this.onChange,
      Key? key})
      : super(key: key);

  @override
  State<StatefulWidget> createState() => __LMultiPickerView();
}

class __LMultiPickerView extends State<_LMultiPickerView> {
  late List<LMultiPickerItem> values;
  @override
  void initState() {
    super.initState();
    values = [];
    LMultiPickerItem? firstUseValue;
    if (widget.values?.isNotEmpty == true) {
      firstUseValue =
          firstWhereOrNull(widget.items, (i) => i.value == widget.values![0]);
    }
    firstUseValue ??= widget.items[0];
    firstUseValue.index = widget.items.indexOf(firstUseValue);
    // 找到一第层的值
    values.add(firstUseValue);
    if (firstUseValue.children?.isNotEmpty == true) {
      // 如果第一层的children不为空 则一定有第二层
      LMultiPickerItem? secondUseValue;
      if ((widget.values?.length ?? 0) > 1) {
        secondUseValue = firstWhereOrNull(
            firstUseValue.children!, (i) => i.value == widget.values![1]);
      }
      secondUseValue ??= firstUseValue.children![0];
      secondUseValue.index = firstUseValue.children!.indexOf(secondUseValue);
      values.add(secondUseValue);
      if (secondUseValue.children?.isNotEmpty == true) {
        // 如果第二层的children不为空 则一定有第三层
        LMultiPickerItem? thirdUseValue;
        if ((widget.values?.length ?? 0) > 2) {
          thirdUseValue = firstWhereOrNull(
              secondUseValue.children!, (i) => i.value == widget.values![2]);
        }
        thirdUseValue ??= secondUseValue.children![0];
        thirdUseValue.index = secondUseValue.children!.indexOf(thirdUseValue);
        values.add(thirdUseValue);
        if (thirdUseValue.children?.isNotEmpty == true) {
          // 如果第三层的children不为空 则一定有第四层
          LMultiPickerItem? fourthUseValue;
          if ((widget.values?.length ?? 0) > 3) {
            fourthUseValue = firstWhereOrNull(
                thirdUseValue.children!, (i) => i.value == widget.values![3]);
          }
          fourthUseValue ??= thirdUseValue.children![0];
          fourthUseValue.index =
              thirdUseValue.children!.indexOf(fourthUseValue);
          values.add(fourthUseValue);
          if (fourthUseValue.children?.isNotEmpty == true) {
            // 如果第四层的children不为空 则一定有第五层
            LMultiPickerItem? fifthUseValue;
            if ((widget.values?.length ?? 0) > 4) {
              fifthUseValue = firstWhereOrNull(fourthUseValue.children!,
                  (i) => i.value == widget.values![4]);
            }
            fifthUseValue ??= fourthUseValue.children![0];
            fifthUseValue.index =
                fourthUseValue.children!.indexOf(fifthUseValue);
            values.add(fifthUseValue);
          }
        }
      }
    }
  }

  /// 根据值 后去值所在的列
  List<LMultiPickerItem> getListForValue(String value) {
    var index = values.indexWhere((i) => i.value == value) - 1;
    if (index < 0) {
      return widget.items;
    }
    return values[index].children!;
  }

  handleChange(LScrollWheelItem oldValue, LScrollWheelItem newValue) {
    if (oldValue.value == newValue.value) return;
    List<LMultiPickerItem> newValues = [];
    for (var i = 0; i < values.length; i++) {
      if (values[i].value != oldValue.value) {
        newValues.add(values[i]);
      } else {
        if (i == 0) {
          var item =
              widget.items.firstWhere((item) => item.value == newValue.value);
          item.index = widget.items.indexOf(item);
          newValues.add(item);
        } else {
          var item = newValues[i - 1]
              .children!
              .firstWhere((item) => item.value == newValue.value);
          item.index = newValues[i - 1].children!.indexOf(item);
          newValues.add(item);
        }
        break;
      }
    }
    for (var i = 0; i < values.length; i++) {
      if (newValues.length <= i) {
        var item = newValues[i - 1].children![0];
        item.index = 0;
        newValues.add(item);
      }
    }
    setState(() {
      values = newValues;
    });
  }

  @override
  Widget build(BuildContext context) {
    var defaultWidth = lrpx(48);
    return LBox(
      backgroundColor: Colors.white,
      borderRadius: [lrpx(10), lrpx(10), 0, 0],
      mainAxisSize: MainAxisSize.min,
      children: [
        LBox(
          height: defaultWidth,
          borderBottom: BorderSide(color: LUI.instance.borderColor),
          direction: BoxDirections.horizontal,
          children: [
            LBox(
                child: '取消',
                width: defaultWidth,
                height: defaultWidth,
                alignment: Alignment.center,
                onTap: widget.onCancel),
            LBox(
              flex: 1,
              child: widget.title,
              fontSize: LStyle.fontSize + lrpx(2),
              fontWeight: FontWeight.bold,
              alignment: Alignment.center,
            ),
            LBox(
              child: '确定',
              width: defaultWidth,
              height: defaultWidth,
              alignment: Alignment.center,
              color: LUI.instance.primaryColor,
              onTap: () => widget.onChange(values),
            ),
          ],
        ),
        LBox(
            direction: BoxDirections.horizontal,
            children: values.map((valueItem) {
              return LBox(
                flex: 1,
                child: LScrollWheel(
                  items: getListForValue(valueItem.value),
                  itemHeight: widget.itemHeight,
                  value: valueItem.value,
                  onChange: (v) => handleChange(valueItem, v),
                ),
              );
            }).toList()),
      ],
    );
  }
}
